//
//  TriangleShape.h
//  Ray Tracer
//
//  Created by Kaila, Ashish on 4/13/13.
//  Copyright (c) 2013 Kaila, Ashish. All rights reserved.
//

#ifndef __Ray_Tracer__TriangleShape__
#define __Ray_Tracer__TriangleShape__

#include "scene_object.h"
#include "../Materials/ITextureMapper.h"

class TriangleShape : public SceneObject, public ITextureMapper
{
public:
    
    // Constructor
    // Note: Vertices must be in clockwise winding
    TriangleShape(Point3D firstVertex,
                  Point3D secondVertex,
                  Point3D thirdVertex,
                  const Material* material);
    
    // Intersection
    bool intersect(Ray3D& ray,
                   const Matrix4x4& worldToModel,
                   const Matrix4x4& modelToWorld) const;
    
    // Returns true if world point is contained within the object
    virtual bool contains(const Point3D& worldPoint, const Matrix4x4& worldToModel) const;
    
    // Maps the texture points
    void setTexturePoint(unsigned int vertexIndex, const double texturePointX, const double texturePointY);
    
    // Set normals
    void setNormals(unsigned int normalIndex, Vector3D& normal);
    
    // Maps a texture to an intersection point
    // intersection - intersection information
    // i - x component of mapped texture coordinate
    // j - y component of mapped texture coordinate
    bool mapTexture(const Intersection& intersection, double& i, double& j) const;
    
    // Returns the texture mapper for the shape
    virtual const ITextureMapper& getTextureMapper() const;
    
private:
    
    // Returns true if a point in an object space lies within the triangle
    bool contains(const Point3D& objectInPointSpace) const;
    
    // Calculates barycentric coordinates for a given point
    void calculateBarycentricCoordinates(Point3D point, double& a, double& b, double&c) const;
    
private:
    Point3D _vertices[3];
    Vector3D _normals[3];
    std::pair<double, double> _texturePoints[3];
};

#endif /* defined(__Ray_Tracer__TriangleShape__) */
